package com.bruce.log.mdc;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.util.StatusPrinter;
import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.io.File;
import java.util.Map;

/**
 * @author xin.ding
 * @date 2021/5/17 10:20
 */
public class LogUtils {
    /** logger */
    private static Logger logger = LoggerFactory.getLogger(LogUtils.class);

    /** config文件目录名称 */
    private static final String CONFIG_PATH = "conf";

    /** logback配置文件名称 */
    private static final String LOGBACK_PATH = File.separator + CONFIG_PATH + File.separator + "logback.xml";

    /** 日志输出默认文件夹 */
    private static final String DEFAULT_LOG_PATH = "logs";

    /** logback.xml中动态日志文件名 */
    private static final String LOG_FILE = "logFileName";

    /**
     * 初始化外部日志配置文件
     */
    static {
        init();
    }

    /**
     * 设置日志输出文件名称
     *
     * @param fileName 文件名称
     */
    public static void setLogFile(String fileName) {
        if (StrUtil.isEmpty(fileName)) {
            throw new NullPointerException("日志文件名称为空!");
        }

        MDC.put(LOG_FILE, fileName);
    }

    /**
     * 设置日志输出目录
     *
     * @param dirName  目录名称
     * @param fileName 文件名称
     */
    public static void setLogFile(String dirName, String fileName) {
        setLogFile(false, dirName, fileName);
    }

    /**
     * 设置日志输出目录
     *
     * @param appendPrefix 是否拼接logs/前缀
     * @param dirName      目录名称
     * @param fileName     文件名称
     */
    public static void setLogFile(boolean appendPrefix, String dirName, String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        if (appendPrefix) {
            stringBuilder.append(DEFAULT_LOG_PATH).append(File.separator);
        }

        if (StrUtil.isNotEmpty(dirName)) {
            stringBuilder.append(dirName).append(File.separator).append(fileName);
        } else {
            stringBuilder.append(fileName);
        }

        setLogFile(stringBuilder.toString());
    }

    /***
     * 获取当前线程Context
     * @return
     */
    public static Map<String, String> getContextMap() {
        return MDC.getCopyOfContextMap();
    }

    /**
     * 设置当前线程Context
     *
     * @param map
     */
    public static void setContextMap(Map<String, String> map) {
        MDC.setContextMap(map);
    }

    /**
     * 清除MDC
     */
    public static void clear() {
        MDC.clear();
    }

    /**
     * 初始化外部日志配置文件
     */
    private static void init() {
        String logbackConfigPath = System.getProperty("user.dir") + LOGBACK_PATH;
        File file = new File(logbackConfigPath);
        if (!file.exists()) {
            logger.error("logbackConfigPath file is no exist,use default config");
        } else {
            if (!file.isFile()) {
                logger.debug("logbackConfigPath file is not a file");
            } else {
                if (!file.canRead()) {
                    logger.debug("logbackConfigPath file can not read");
                } else {
                    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
                    JoranConfigurator joranConfigurator = new JoranConfigurator();
                    joranConfigurator.setContext(loggerContext);
                    loggerContext.reset();
                    try {
                        joranConfigurator.doConfigure(file);
                    } catch (Exception e) {
                        logger.error("logbackConfigPath Load logback config file error. Message: {}", e.getMessage());
                    }
                    StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
                }
            }
        }
    }
}

